/**
 * Copyright 2024 Inc.
 **/
package com.myz.java.study.juc.lock;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.locks.LockSupport;

/**
 * @author maoyz0621 on 2024/1/16
 * @version v1.0
 */
@Slf4j
public class LockSupport1Test {

    /**
     * 使用park和unpark实现线程同步
     */
    public static void main(String[] args) {
        Thread thread = new Thread(new MyThread(Thread.currentThread()));
        thread.start();

        // 这样就限制性unpark，后执行park
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info("before park");
        LockSupport.park("LockSupportTest-blocker");
        log.info("after park");

        /******************************** 先park 后unpark ****************************************/
        // main | com.myz.java.study.juc.lock.LockSupportTest | before park
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | start unpark
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | Blocker info: LockSupportTest-blocker
        // main | com.myz.java.study.juc.lock.LockSupportTest | after park
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | Blocker info: null
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | after unpark


        /******************************** 先unpark 后park ****************************************/
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | start unpark
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | Blocker info: null
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | after unpark Blocker info: null
        // Thread-0 | com.myz.java.study.juc.lock.LockSupportTest | after unpark
        // main | com.myz.java.study.juc.lock.LockSupportTest | before park
        // main | com.myz.java.study.juc.lock.LockSupportTest | after park

    }

    static class MyThread implements Runnable {
        private Object obj;

        public MyThread(Object obj) {
            this.obj = obj;
        }

        @Override
        public void run() {
            log.info("start unpark");

            try {
                Thread.sleep(1000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            log.info("Blocker info: {}", LockSupport.getBlocker((Thread) obj));

            // 1. 唤醒线程：使用LockSupport.unpark
            LockSupport.unpark((Thread) obj);

            try {
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            log.info("after unpark Blocker info: {}", LockSupport.getBlocker((Thread) obj));
            log.info("after unpark");
        }
    }
}